#include "SubsystemBedWars.h"
#include "Managers/GameManager.h"
#include "Components/ComponentPlayer.h"
#include "Components/ComponentBody.h"
#include "Components/ComponentClothing.h"
#include "Components/ComponentHealth.h"
#include "Components/ComponentMiner.h"
#include "Components/ComponentInventory.h"
#include "Components/ComponentCraftingTable.h"
#include "Components/ComponentChest.h"
#include "BedWars.h"
#include "GameSingleton.h"
#include "GameRandom.hpp"
#include "GameRegistry.hpp"
#include "Subsystems/BlockBehaviors/SubsystemSignBlockBehavior.h"
#include "Network/PackageManager.h"
#include "Network/Packages/MessagePackage.h"
#include "SubsystemBedWarsTerrain.h"
#include "Subsystems/SubsystemPlayers.h"
#include "Subsystems/SubsystemPickables.h"
#include "Player/PlayerData.h"
#include "Log.h"
#include "Blocks/ClothingBlock.h"
#include "Blocks/IronMacheteBlock.h"
#include "Blocks/CopperMacheteBlock.h"

#include "Blocks/WoodenSpearBlock.h"
#include "Blocks/WoodenClubBlock.h"
#include "Blocks/OakWoodBlock.h"

namespace BedWars
{
    SubsystemBedWars::SubsystemBedWars()
    {
        teamNames[0] = "红队";
        teamNames[1] = "蓝队";
        teamNames[2] = "绿队";
        teamNames[3] = "紫队";
        changeStatue(BedWarsStatue::Prepare);
    }

    void SubsystemBedWars::changeStatue(BedWarsStatue statue)
    {
        for(uint8_t index = 0; index < 4; ++index)
        {
            teamSignNeedUpdate[index] = true;
        }
        m_produceTime = 0.0f;
        ironProduceCount = 0;
        diamondProductCount = 0;
        realDead = false;
        deadTime = 0.0f;
        injureBaseValue = 0.0f;
        canRestart = true;
        switch (statue)
        {
        case BedWarsStatue::Prepare:
            m_gameTime = 60;
            break;
        case BedWarsStatue::Countdown:
            {
                mainStatue = statue;

                m_gameTime = 10;
                m_lastTime = 10;
                for(uint8_t index = 0; index < 4; ++index)
                {
                    bedHealth[index] = bedWarsCore->bedBreakCount;
                }
                for(auto &pair : playerTeamMap)
                {
                    if(pair.second != TeamType::None)
                    {
                        entt::entity entity = (entt::entity)pair.first;
                        ComponentPlayer **componentPlayerPtr = GameSingleton::gameRegistry->try_get<ComponentPlayer*>(entity);
                        if(componentPlayerPtr != nullptr)
                        {
                            toTeamHomePosition(*componentPlayerPtr);
                        }
                    }
                }
                GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>("10秒后游戏开始", "玩法：挖掉其它队伍的石碑，没有石碑的队伍不能复活玩家\n箱子是商店，上一行是商品，下一行是价格\n买物品的时候直接拖动商品即可\n铜锭出生点就有，铁锭附近的小岛有，钻石中间的大岛有", 5.0f, 0.0f));
            }
            break;
        case BedWarsStatue::GameRunning:
            {
                for(auto &pair : playerTeamMap)
                {
                    if(pair.second != TeamType::None)
                    {
                        entt::entity entity = (entt::entity)pair.first;
                        ComponentPlayer **componentPlayerPtr = GameSingleton::gameRegistry->try_get<ComponentPlayer*>(entity);
                        if(componentPlayerPtr != nullptr)
                        {
                            toTeamHomePosition(*componentPlayerPtr);
                        }
                    }
                }
                m_gameTime = 1200;
                GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>("游戏开始", "挖掉其它队伍的石碑，没有石碑的队伍不能复活玩家\n箱子是商店，上一行是商品，下一行是价格\n买物品的时候直接拖动商品即可\n铜锭出生点就有，铁锭附近的小岛有，钻石中间的大岛有", 5.0f, 0.0f));
            }
            break;
        case BedWarsStatue::Ending:
            {
                terrainClear();
                m_gameTime = 10;
                uint8_t teamIndex = UINT8_MAX;
                SignTextData signTextData;
                for(uint8_t index = 0; index < 4; ++index)
                {
                    if(signBlockBehavior->getSignData(bedWarsCore->teamData[index].joinSignPoint, signTextData))
                    {
                        if(teamEntitySet[index].size() > 0)
                        {
                            teamIndex = index;
                            signTextData.lines[1] = "获胜";
                        }
                        else
                        {
                            signTextData.lines[1] = "失败";
                        }
                        signTextData.lines[2] = "";
                        signTextData.lines[3] = "";
                        signBlockBehavior->setSignData(signTextData);
                    }
                }

                if(teamIndex != UINT8_MAX)
                {
                    GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>(
                        "游戏结束", 
                        fmt::format("恭喜 {} 获得胜利", getTeamName((TeamType)teamIndex)),
                        5.0f, 
                        0.0f));
                }
                else
                {
                    GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>(
                        "游戏结束", 
                        "没有队伍存活，没有获胜的队伍",
                        5.0f, 
                        0.0f));
                }
            }
            break;
        }

        mainStatue = statue;
    }

    void SubsystemBedWars::update(float dt)
    {
        if(bedWarsCore->isEditMode == false)
        {
            std::vector<std::shared_ptr<PlayerData>> playerDataVec;
            subsystemPlayers->getAllPlayerData(playerDataVec);
            switch (mainStatue)
            {
            case BedWarsStatue::Prepare:
                {
                    for (std::shared_ptr<PlayerData> &playerData : playerDataVec)
                    {
                        if(playerData->componentPlayer == nullptr)
                        {
                            continue;
                        }
                        // bool needChangePosition = false;
                        // ComponentBody *componentBody = playerData->componentPlayer->componentBody;

                        // componentBody->positionMutex.lock();
                        // needChangePosition = componentBody->position.posY < bedWarsCore->limitHeight;
                        // componentBody->positionMutex.unlock();

                        // if(needChangePosition)
                        // {
                        //     playerData->componentPlayer->setNetPosition(bedWarsCore->respawnPosition);
                        // }

                        // Vector3 realPosition = playerData->componentPlayer->componentBody->getRealPosition();

                        Vector3 position;
                        playerData->componentPlayer->componentBody->getPosition(position);

                        if(position.posY < bedWarsCore->limitHeight)
                        {
                            playerData->componentPlayer->setNetPosition(bedWarsCore->respawnPosition);
                        }
                    }
                }
                break;
            case BedWarsStatue::GameRunning:
            case BedWarsStatue::Ending:
                {
                    for (std::shared_ptr<PlayerData> &playerData : playerDataVec)
                    {
                        if(playerData->componentPlayer == nullptr)
                        {
                            continue;
                        }
                        TeamType ranksType = getEntityTeam(playerData->entity);

                        // std::lock_guard<std::recursive_mutex> lk(playerData->componentPlayer->componentBody->positionMutex);

                        Vector3 realPosition;
                        playerData->componentPlayer->componentBody->getPosition(realPosition);

                        if(ranksType == TeamType::None)
                        {
                            if(realPosition.posY < bedWarsCore->limitHeight)
                            {
                                playerData->componentPlayer->setNetPosition(bedWarsCore->respawnPosition);
                            }
                        }
                        else
                        {
                            if(realPosition.posY < 0.0f)
                            {
                                // playerData->componentPlayer->componentHealth->injure(999.0f, entt::null, true, "越界被处死", InjureType::Plugin);

                                // 有无敌时间，但是却掉入虚空，则直接传送会出生点吧
                                if (playerData->componentPlayer->componentHealth->invincibleTime > 0)
                                {
                                    toTeamHomePosition(playerData->componentPlayer);
                                }
                                else
                                {
                                    playerData->componentPlayer->componentHealth->injure(999.0f, entt::null, true, "越界被处死", InjureType::Plugin);
                                }
                            }
                            else if(realPosition.posY >= bedWarsCore->limitHeight + 3)
                            {
                                playerData->componentPlayer->componentHealth->injure(0.1f, entt::null, true, "越界被处死", InjureType::Unknow);
                            }
                        }



                    }
                }
                break;
            }



            switch (mainStatue)
            {
            case BedWarsStatue::Prepare:
                {
                    m_gameTime -= dt;
                    if(m_gameTime < 0)
                    {
                        uint8_t residue = 0;
                        for(uint8_t index = 0; index < 4; ++index)
                        {
                            if(teamEntitySet[index].size() > 0)
                            {
                                residue++;
                            }
                        }
                        if(residue >= 2)
                        {
                            terrainClear();
                            changeStatue(BedWarsStatue::Countdown);
                            break;
                        }
                        else
                        {
                            m_gameTime = 20;
                        }
                    }
                    else
                    {
                        if(teamSignNeedUpdate[0] == true)
                        {
                            teamSignNeedUpdate[0] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[0].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入红队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[0].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = "";
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[1] == true)
                        {
                            teamSignNeedUpdate[1] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[1].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入蓝队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[1].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = "";
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[2] == true)
                        {
                            teamSignNeedUpdate[2] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[2].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入绿队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[2].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = "";
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[3] == true)
                        {
                            teamSignNeedUpdate[3] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[3].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入紫队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[3].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = "";
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                    }
                }
                break;
            case BedWarsStatue::Countdown:
                {
                    m_gameTime -= dt;

                    if(m_gameTime < 0)
                    {
                        uint8_t residue = 0;
                        for(uint8_t index = 0; index < 4; ++index)
                        {
                            if(teamEntitySet[index].size() > 0)
                            {
                                residue++;
                            }
                        }
                        if(residue >= 2)
                        {
                            changeStatue(BedWarsStatue::GameRunning);
                        }
                        else
                        {
                            GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>("", "人数不足，回到准备阶段", 5.0f, 0.0f));
                            changeStatue(BedWarsStatue::Prepare);
                        }
                        break;
                    }
                    else
                    {
                        if(m_lastTime != (int32_t)m_gameTime)
                        {
                            m_lastTime = (int32_t)m_gameTime;
                            for(uint8_t index = 0; index < 4; ++index)
                            {
                                teamSignNeedUpdate[index] = true;
                            }
                        }

                        if(teamSignNeedUpdate[0] == true)
                        {
                            teamSignNeedUpdate[0] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[0].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入红队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[0].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = fmt::format("倒计时: {}", m_lastTime);
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[1] == true)
                        {
                            teamSignNeedUpdate[1] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[1].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入蓝队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[1].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = fmt::format("倒计时: {}", m_lastTime);
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[2] == true)
                        {
                            teamSignNeedUpdate[2] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[2].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入绿队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[2].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = fmt::format("倒计时: {}", m_lastTime);
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                        if(teamSignNeedUpdate[3] == true)
                        {
                            teamSignNeedUpdate[3] = false;
                            SignTextData signTextData;
                            if(signBlockBehavior->getSignData(bedWarsCore->teamData[3].joinSignPoint, signTextData))
                            {
                                signTextData.lines[0] = "[点击加入紫队]";
                                signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[3].size(), bedWarsCore->teamPlayerCount);
                                signTextData.lines[2] = "准备中...";
                                signTextData.lines[3] = fmt::format("倒计时: {}", m_lastTime);
                                signBlockBehavior->setSignData(signTextData);
                            }
                        }
                    }

                }
                break;
            case BedWarsStatue::GameRunning:
                {
                    m_gameTime -= dt;
                    m_produceTime += dt;
                    if(m_gameTime < 0)
                    {
                        if(realDead == false)
                        {
                            m_gameTime = 300;
                            GameSingleton::packageManager->addSendPackageToQueue(std::make_shared<MessagePackage>("即将进入死亡模式", "石标复活已经失效，5分钟后进入死亡模式\n届时所有玩家每秒都会受到百分比的真实伤害\n有石碑的队伍受到的伤害会减少", 10.0f, 0.0f));
                            realDead = true;
                            canRestart = false;
                        }
                        else
                        {
                            m_gameTime = 5.0f;
                            injureBaseValue += 0.01f;

                            std::set<entt::entity> teamEntitySetCopy[4];
                            m_teamMutex.lock();
                            teamEntitySetCopy[0] = teamEntitySet[0];
                            teamEntitySetCopy[1] = teamEntitySet[1];
                            teamEntitySetCopy[2] = teamEntitySet[2];
                            teamEntitySetCopy[3] = teamEntitySet[3];
                            m_teamMutex.unlock();


                            for(uint8_t index = 0; index < 4;++index)
                            {
                                float injureValue = injureBaseValue;
                                if(bedHealth[index] > 0)
                                {
                                    injureValue /= 1.5f;
                                }
                                for(entt::entity entity : teamEntitySetCopy[index])
                                {
                                    ComponentHealth *componentHealth = GameSingleton::gameRegistry->get<ComponentHealth*>(entity);
                                    componentHealth->injure(injureValue, entt::null, true, "被幽灵杀戮");
                                }
                            }
                        }
                    }

                    if(m_produceTime >= 3.0f)
                    {
                        m_produceTime = 0;

                        uint8_t residue = 0;
                        for(uint8_t index = 0; index < 4; ++index)
                        {
                            if(teamEntitySet[index].size() > 0)
                            {
                                residue++;
                            }
                        }
                        if(residue <= 1)
                        {
                            changeStatue(BedWarsStatue::Ending);
                            break;
                        }

                        produceSourcePickable(1);
                    }

                    if(teamSignNeedUpdate[0] == true)
                    {
                        teamSignNeedUpdate[0] = false;
                        SignTextData signTextData;
                        if(signBlockBehavior->getSignData(bedWarsCore->teamData[0].joinSignPoint, signTextData))
                        {
                            signTextData.lines[0] = "[红队]";
                            signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[0].size(), bedWarsCore->teamPlayerCount);
                            signTextData.lines[2] = fmt::format("生命: {}/{}", bedHealth[0], bedWarsCore->bedBreakCount);
                            signTextData.lines[3] = "进行中...";
                            signBlockBehavior->setSignData(signTextData);
                        }
                    }
                    if(teamSignNeedUpdate[1] == true)
                    {
                        teamSignNeedUpdate[1] = false;
                        SignTextData signTextData;
                        if(signBlockBehavior->getSignData(bedWarsCore->teamData[1].joinSignPoint, signTextData))
                        {
                            signTextData.lines[0] = "[蓝队]";
                            signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[1].size(), bedWarsCore->teamPlayerCount);
                            signTextData.lines[2] = fmt::format("生命: {}/{}", bedHealth[1], bedWarsCore->bedBreakCount);
                            signTextData.lines[3] = "进行中...";
                            signBlockBehavior->setSignData(signTextData);
                        }
                    }
                    if(teamSignNeedUpdate[2] == true)
                    {
                        teamSignNeedUpdate[2] = false;
                        SignTextData signTextData;
                        if(signBlockBehavior->getSignData(bedWarsCore->teamData[2].joinSignPoint, signTextData))
                        {
                            signTextData.lines[0] = "[绿队]";
                            signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[2].size(), bedWarsCore->teamPlayerCount);
                            signTextData.lines[2] = fmt::format("生命: {}/{}", bedHealth[2], bedWarsCore->bedBreakCount);
                            signTextData.lines[3] = "进行中...";
                            signBlockBehavior->setSignData(signTextData);
                        }
                    }
                    if(teamSignNeedUpdate[3] == true)
                    {
                        teamSignNeedUpdate[3] = false;
                        SignTextData signTextData;
                        if(signBlockBehavior->getSignData(bedWarsCore->teamData[3].joinSignPoint, signTextData))
                        {
                            signTextData.lines[0] = "[紫队]";
                            signTextData.lines[1] = fmt::format("人数: {}/{}", teamEntitySet[3].size(), bedWarsCore->teamPlayerCount);
                            signTextData.lines[2] = fmt::format("生命: {}/{}", bedHealth[3], bedWarsCore->bedBreakCount);
                            signTextData.lines[3] = "进行中...";
                            signBlockBehavior->setSignData(signTextData);
                        }
                    }
                }
                break;
            case BedWarsStatue::Ending:
                {
                    m_gameTime -= dt;
                    if(m_gameTime < 0)
                    {
                        terrainClear();
                        teamClear();
                        changeStatue(BedWarsStatue::Prepare);
                        break;
                    }
                    else
                    {
                        // 放烟花
                    }
                }
                break;
            }
        }
    }

    TeamType SubsystemBedWars::getEntityTeam(entt::entity entity)
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        auto it = playerTeamMap.find((uint16_t)entity);
        if(it != playerTeamMap.end())
        {
            return it->second;
        }
        return TeamType::None;
    }

    bool SubsystemBedWars::joinTeam(entt::entity entity, TeamType teamType)
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        uint8_t teamIndex = (uint8_t)teamType;
        if(teamEntitySet[teamIndex].size() < bedWarsCore->teamPlayerCount)
        {
            playerTeamMap[(uint16_t)entity] = teamType;
            teamEntitySet[teamIndex].insert(entity);
            teamSignNeedUpdate[teamIndex] = true;
            return true;
        }
        return false;
    }

    bool SubsystemBedWars::exitTeam(entt::entity entity)
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        auto it = playerTeamMap.find((uint16_t)entity);
        if(it != playerTeamMap.end())
        {
            uint8_t teamIndex = (uint8_t)(it->second);
            if(teamIndex > 4)
            {
                return false;
            }
            playerTeamMap.erase(it);

            auto setIt = teamEntitySet[teamIndex].find(entity);
            if(setIt != teamEntitySet[teamIndex].end())
            {
                teamEntitySet[teamIndex].erase(setIt);
                teamSignNeedUpdate[teamIndex] = true;
                return true;
            }
        }
        return false;
    }

    void SubsystemBedWars::resetPlayer(PocketSurvival::ComponentPlayer *componentPlayer)
    {
        // 清空衣服
        PocketSurvival::ComponentClothing *componentClothing = componentPlayer->componentClothing;
        componentClothing->clothes[0].clear();
        componentClothing->clothes[1].clear();
        componentClothing->clothes[2].clear();
        componentClothing->clothes[3].clear();
        componentClothing->onSlotChange(0);
        componentClothing->onSlotChange(1);
        componentClothing->onSlotChange(2);
        componentClothing->onSlotChange(3);

        // 不是创造背包的话就清空
        PocketSurvival::IInventory * inventory = componentPlayer->componentMiner->inventory;
        if(dynamic_cast<PocketSurvival::ComponentInventory*>(inventory) != nullptr)
        {
            for(uint32_t index = 0; index < inventory->slotsCount(); ++index)
            {
                inventory->setSlotValue(index, 0, 0);
                inventory->onSlotChange(index);
            }
        }
        // 清空合成表
        for(uint32_t index = 0; index < componentPlayer->componentCraftingTable->slotsCount(); ++index)
        {
            componentPlayer->componentCraftingTable->setSlotValue(index, 0, 0);
            componentPlayer->componentCraftingTable->onSlotChange(index);
        }

        // 生命值恢复满
        if(componentPlayer->componentHealth->health > 0.0f)
        {
            componentPlayer->componentHealth->heal(1.0f);
        }

        componentPlayer->playerData->level = 2;
    }

    void SubsystemBedWars::onEntityAdded(entt::entity entity)
    {
        if(bedWarsCore->isEditMode == false)
        {
            PocketSurvival::ComponentPlayer **componentPlayerPtr = GameSingleton::gameRegistry->try_get<PocketSurvival::ComponentPlayer*>(entity);
            if(componentPlayerPtr != nullptr)
            {
                PocketSurvival::ComponentPlayer *componentPlayer = *componentPlayerPtr;
                PocketSurvival::ComponentBody *componentBody = componentPlayer->componentBody;

                componentBody->setPosition(bedWarsCore->respawnPosition);

                PocketSurvival::ComponentHealth *componentHealth = componentPlayer->componentHealth;
                componentHealth->health = 1.0f;


                // 清空衣服
                PocketSurvival::ComponentClothing *componentClothing = componentPlayer->componentClothing;
                componentClothing->clothes[0].clear();
                componentClothing->clothes[1].clear();
                componentClothing->clothes[2].clear();
                componentClothing->clothes[3].clear();
                // 不是创造背包的话就清空
                PocketSurvival::IInventory * inventory = componentPlayer->componentMiner->inventory;
                if(dynamic_cast<PocketSurvival::ComponentInventory*>(inventory) != nullptr)
                {
                    // Log::info("get slots count");
                    uint32_t slotsCount = inventory->slotsCount();
                    // Log::info(fmt::format("slots count : {}", slotsCount));
                    for(uint32_t index = 0; index < slotsCount; ++index)
                    {
                        // Log::info(fmt::format("set index {}", index));
                        inventory->setSlotValue(index, 0, 0);
                    }
                }
                // 清空合成表
                for(uint32_t index = 0; index < componentPlayer->componentCraftingTable->slotsCount(); ++index)
                {
                    componentPlayer->componentCraftingTable->setSlotValue(index, 0, 0);
                }

            }
        }
    }

    // 换上队伍专属的服装
    void SubsystemBedWars::setTeamClothes(PocketSurvival::ComponentPlayer *componentPlayer, TeamType teamType)
    {
        static const std::vector<int32_t> teamClothes[4][4] = {
            std::vector<int32_t>(1, 940015819),
            std::vector<int32_t>(1, 939753675),
            std::vector<int32_t>(1, 939786443),
            std::vector<int32_t>(1, 939950283),

            std::vector<int32_t>(1, 738689227),
            std::vector<int32_t>(1, 738427083),
            std::vector<int32_t>(1, 738459851),
            std::vector<int32_t>(1, 738623691),

            std::vector<int32_t>(1, 872906955),
            std::vector<int32_t>(1, 872644811),
            std::vector<int32_t>(1, 872677579),
            std::vector<int32_t>(1, 872841419),

            std::vector<int32_t>(1, 671580363),
            std::vector<int32_t>(1, 671318219),
            std::vector<int32_t>(1, 671350987),
            std::vector<int32_t>(1, 671514827)
        };

        ComponentClothing *componentClothing = componentPlayer->componentClothing;
        componentClothing->setClothes(ClothingSlot::Head,  teamClothes[(uint8_t)teamType][0]);
        componentClothing->setClothes(ClothingSlot::Torso, teamClothes[(uint8_t)teamType][1]);
        componentClothing->setClothes(ClothingSlot::Legs,  teamClothes[(uint8_t)teamType][2]);
        componentClothing->setClothes(ClothingSlot::Feet,  teamClothes[(uint8_t)teamType][3]);
    }
    
    void SubsystemBedWars::addBaseTools(PocketSurvival::ComponentPlayer *componentPlayer)
    {
        if(componentPlayer->playerData->gameMode != GameMode::Creative)
        {
            IInventory *inventory = componentPlayer->componentMiner->inventory;
            inventory->setSlotValue(0, WoodenClubBlock::Index(), 1);
            inventory->setSlotValue(1, WoodenSpearBlock::Index(), 1);
            inventory->setSlotValue(2, 9, 1);
        }
    }


    void SubsystemBedWars::onEntityRemoved(entt::entity entity)
    {
        exitTeam(entity);
    }

    // 传送到对应队伍的出生点，没有队伍的会被传送到大厅出生点
    void SubsystemBedWars::toTeamHomePosition(PocketSurvival::ComponentPlayer *componentPlayer)
    {
        TeamType teamType = getEntityTeam(componentPlayer->entity);
        if(teamType != TeamType::None)
        {
            if(mainStatue >= BedWarsStatue::Countdown)
            {
                float offsetX = GameSingleton::gameRandom->getFloat(-3.5f, 3.5f);
                float offsetZ = GameSingleton::gameRandom->getFloat(-3.5f, 3.5f);
                Vector3 position = bedWarsCore->teamData[(uint8_t)teamType].startPosition;
                position.posX += offsetX;
                position.posZ += offsetZ;
                componentPlayer->setNetPosition(position);
                return;
            }
        }
        componentPlayer->setNetPosition(bedWarsCore->respawnPosition);
    }

    const std::string &SubsystemBedWars::getTeamName(TeamType teamType)
    {
        if(teamType != TeamType::None)
        {
            return teamNames[(uint8_t)teamType];
        }
        static const std::string noTeamText = "无";
        return noTeamText;
    }

    uint8_t SubsystemBedWars::decTeamHealth(TeamType teamType)
    {
        uint8_t teamIndex = (uint8_t)teamType;
        std::lock_guard<std::mutex> lk(m_bedHealthMutex);
        if(bedHealth[teamIndex] > 0)
        {
            teamSignNeedUpdate[teamIndex] = true;
            --bedHealth[teamIndex];

            if(bedHealth[teamIndex] == 0)
            {
                std::set<entt::entity> teamSet = teamEntitySet[teamIndex];
                for(entt::entity entity : teamSet)
                {
                    ComponentHealth *componentHealth = GameSingleton::gameRegistry->get<ComponentHealth*>(entity);
                    if(componentHealth->health <= 0.0f)
                    {
                        exitTeam(entity);
                    }
                }
            }
        }
        return bedHealth[teamIndex];
    }

   
    uint32_t SubsystemBedWars::getTeamPlayerCount(TeamType teamType)
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        return teamEntitySet[(uint8_t)teamType].size();
    }

    void SubsystemBedWars::teamClear()
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        for(auto &pair : playerTeamMap)
        {
            if(pair.second != TeamType::None)
            {
                entt::entity entity = (entt::entity)pair.first;
                ComponentPlayer **componentPlayerPtr = GameSingleton::gameRegistry->try_get<ComponentPlayer*>(entity);
                if(componentPlayerPtr != nullptr)
                {
                    resetPlayer(*componentPlayerPtr);
                    (*componentPlayerPtr)->setNetPosition(bedWarsCore->respawnPosition);
                    // toTeamHomePosition(*componentPlayerPtr);
                }
            }
        }
        playerTeamMap.clear();
        teamEntitySet[0].clear();
        teamEntitySet[1].clear();
        teamEntitySet[2].clear();
        teamEntitySet[3].clear();
    }

    void SubsystemBedWars::terrainClear()
    {
        SubsystemPlayers *subsystemPlayers = GameSingleton::singletonPtr->getSingleton<SubsystemPlayers>();
        std::vector<Point2> clearChunkVec;
        bedWarsCore->bedWarsTerrain->discardTerrainModify(clearChunkVec);

        Log::Info(fmt::format("地形清理 : {}", clearChunkVec.size()), Log::LogType::TERRAIN);

        std::vector<std::shared_ptr<PlayerData>> playerDataVec;
        subsystemPlayers->getAllPlayerData(playerDataVec);

        subsystemPickables->clearAllPickable();

        for(std::shared_ptr<PlayerData> &playerData : playerDataVec)
        {
            for(Point2 point : clearChunkVec)
            {
                playerData->requestChunk(point);
            }
        }
    }

    void SubsystemBedWars::produceSourcePickable(uint32_t count)
    {
        SubsystemBedWarsTerrain *bedwarsTerrain = bedWarsCore->bedWarsTerrain;

        ironProduceCount += count;
        diamondProductCount += count;
        
        for(const Point3& point : bedWarsCore->resourceSet)
        {
            Vector3 position(point.posX + 0.5f, point.posY + 1.0f, point.posZ + 0.5f);
            int32_t cellContents = bedwarsTerrain->getCellContents(point);
            switch (cellContents)
            {
            case 46:// 铁块
                {
                    if((ironProduceCount / 3) > 0)
                    {
                        subsystemPickables->addPickable(40, ironProduceCount / 3, position, std::make_shared<Vector3>(0.0f, 3.0f, 0.0f), nullptr);
                    }
                }
                break;
            case 47:// 铜块
                {
                    if(count > 0)
                    {
                        subsystemPickables->addPickable(42, count, position, std::make_shared<Vector3>(0.0f, 3.0f, 0.0f), nullptr);
                    }
                }
                break;
            case 126:
                {
                    if((diamondProductCount / 5) > 0)
                    {
                        subsystemPickables->addPickable(111, diamondProductCount / 5, position, std::make_shared<Vector3>(0.0f, 3.0f, 0.0f), nullptr);
                    }
                }
                break;
            }
        }
        ironProduceCount %= 3;
        diamondProductCount %= 5;
    }



    bool SubsystemBedWars::transaction(ComponentChest *chest, uint32_t chestIndex, IInventory *inventory, uint32_t slotIndex)
    {
        int32_t priceBlockValue = chest->getSlotValue(chestIndex + 4);
        uint32_t priceBlockCount = chest->getSlotCount(chestIndex + 4);

        int32_t itemBlockValue = chest->getSlotValue(chestIndex);
        uint32_t itemBlockCount = chest->getSlotCount(chestIndex);

        int32_t targetSlotValue = inventory->getSlotValue(slotIndex);
        uint32_t targetSlotCount = inventory->getSlotCount(slotIndex);

        // Log::info(fmt::format("({},{}) | ({},{}) | ({},{}) ({},{})", priceBlockValue, priceBlockCount, itemBlockValue, itemBlockCount, targetSlotValue, targetSlotCount, slotIndex, inventory->getSlotCapacity(slotIndex, itemBlockValue)));

        if( (itemBlockValue == targetSlotValue || targetSlotCount == 0) &&
            priceBlockValue != 0 &&
            priceBlockCount > 0 &&
            itemBlockValue != 0 &&
            itemBlockCount > 0 && 
            itemBlockCount + targetSlotCount <= inventory->getSlotCapacity(slotIndex, itemBlockValue))
        {
            std::vector<uint32_t> moneySlotIndexVec;
            uint32_t money = 0;
            for(uint32_t index = 0; index < inventory->slotsCount(); ++index)
            {
                if(inventory->getSlotValue(index) == priceBlockValue)
                {
                    money += inventory->getSlotCount(index);
                    moneySlotIndexVec.push_back(index);
                }
            }
            // Log::info(fmt::format("money: {}, price: {}", money, priceBlockCount));
            if(money >= priceBlockCount)
            {
                for(uint32_t index : moneySlotIndexVec)
                {
                    priceBlockCount -= inventory->removeSlotItems(index, priceBlockCount);
                    if(priceBlockCount <= 0)
                    {
                        inventory->addSlotItems(slotIndex, itemBlockValue, itemBlockCount);
                        break;
                    }
                }
            }
        }
        return true;
    }

    void SubsystemBedWars::teamZeroPlayerClear(TeamType teamType)
    {
        std::lock_guard<std::mutex> lk(m_teamMutex);
        std::set<entt::entity> teamSet;
        for(auto entity : teamEntitySet[(uint8_t)teamType])
        {
            ComponentHealth *componentHealth = GameSingleton::gameRegistry->get<ComponentHealth*>(entity);
            if(componentHealth->health > 0)
            {
                teamSet.insert(entity);
            }
            else
            {
                playerTeamMap[(uint16_t)entity] = TeamType::None;
            }
        }
        teamEntitySet[(uint8_t)teamType].swap(teamSet);
    }


    const std::string& SubsystemBedWars::getName() const
    {
        static const std::string subsystemName = "BedWars";
        return subsystemName;
    }
    void SubsystemBedWars::load(const nlohmann::json &json)
    {
        signBlockBehavior = GameSingleton::singletonPtr->getSingleton<SubsystemSignBlockBehavior>();
        subsystemPickables = GameSingleton::singletonPtr->getSingleton<SubsystemPickables>();
        
        subsystemPlayers = GameSingleton::singletonPtr->getSingleton<SubsystemPlayers>();

        GameSingleton::blocksManager->blocks[IronMacheteBlock::Index()]->DefaultMeleeHitProbability = 0.95f;
        GameSingleton::blocksManager->blocks[CopperMacheteBlock::Index()]->DefaultMeleeHitProbability = 0.95f;


        ClothingBlock *clothingBlock = GameSingleton::blocksManager->blocks[ClothingBlock::Index()]->asBlock<ClothingBlock *>();
        std::vector<ClothingData> &clothingDataVec = clothingBlock->clothingDataVec;
        clothingDataVec[30].IsOuter = false;
        clothingDataVec[11].Layer = 2;      // 皮帽
        clothingDataVec[18].Layer = 2;      // 毛皮头盔
        clothingDataVec[33].Layer = 2;      // 铜头盔
        clothingDataVec[10].Layer = 2;      // 铁头盔
        clothingDataVec[21].Layer = 2;      // 钻石头盔

        for(ClothingData & clothingData : clothingDataVec)
        {
            if(clothingData.ArmorProtection >= 0.99f)
            {
                if(clothingData.Sturdiness >= 50 && clothingData.Sturdiness <= 60)
                {
                    clothingData.ArmorProtection *= 0.93f;
                    clothingData.Sturdiness *= 0.9f;
                }
                else if(clothingData.Sturdiness == 100)
                {
                    clothingData.ArmorProtection *= 0.95f;
                    clothingData.Sturdiness *= 0.9f;
                }
                else if(clothingData.Sturdiness >= 200)
                {
                    clothingData.ArmorProtection *= 0.96f;
                    clothingData.Sturdiness *= 0.9f;
                }
                else
                {
                    clothingData.ArmorProtection *= 0.98f;
                }
            }
        }
    }

    PocketSurvival::SubLoadEchelon SubsystemBedWars::getLoadEchelon()
    {
        return PocketSurvival::SubLoadEchelon::Second;
    }

    PocketSurvival::SubUpdateType SubsystemBedWars::getUpdateType()
    {
        return PocketSurvival::SubUpdateType::MultiThreadUpdate;
    }

} // namespace BedWars
